import { AcGameObject } from "./AcGameObject.js";
import { Snake } from "./Snake.js";
import { Wall } from "./Wall.js";

export class GameMap extends AcGameObject {
    constructor(ctx, parent, store) { // ctx表示画布，parent表示画布的父元素
        super(); // 先执行AcGameObject
       
        this.ctx = ctx;
        this.parent = parent;
        this.store = store; // 后端传过来的地图
        this.L = 0; // 地图一个单位的长度
        
        this.rows = 20;
        this.cols = 31;
        this.walls = []; // 存储所有墙

        this.inner_walls_count = 50  // 默认障碍物数量

        this.snakes = [
            new Snake({id: 0, color: "#FD0000", r: this.rows - 2, c: 1}, this),
            new Snake({id: 1, color: "#8424E0", r: 1, c: this.cols - 2}, this),
        ]
    }

    check_ready() { // 判断两条蛇是否准备好下一回合
        for (let snake of this.snakes) {
            if (snake.status !== 'idle') return false;
            if (snake.direction == -1) return false;
        } 

        return true;
    }

    check_connectivity(g, sx, sy, tx, ty) { // 判断地图是否连通
            if (sx == tx && sy == ty) return true;
            g[sx][sy] = true;
            let dx = [-1, 0, 1, 0], dy = [0, 1, 0, -1];
            for (let i = 0; i < 4; i ++ ) {
                let x = dx[i] + sx, y = dy[i] + sy;
                if (!g[x][y] && this.check_connectivity(g, x, y, tx, ty)) 
                    return true;
            }

            return false;
    }

    create_walls() {
        const g = this.store.state.pk.gamemap;
        // 加墙
        for (let r = 0; r < this.rows; r ++ )
            for (let c = 0; c < this.cols; c ++ )
                if (g[r][c]) {
                    this.walls.push(new Wall(r, c, this));
                }

        return true;
    }

    start() {
        this.create_walls();
        for (let i = 0; i < 1000; i ++ ) {
            if (this.create_walls()) {
                break;
            }
        }

        this.add_listening_events();
        
    }

    add_listening_events() { // 绑定监听事件
        if (this.store.state.record.is_record) {
            let k = 0;
            const a_steps = this.store.state.record.a_steps;
            const b_steps = this.store.state.record.b_steps;
            const loser = this.store.state.record.record_loser;
            const [snake0, snake1] = this.snakes;
            const interval_id = setInterval(() => {
                if (k >= a_steps.length - 1) { // 若蛇已死亡
                    if (loser === 'all' || loser === 'A') {
                        snake0.status = "die";
                    }
                    if (loser == 'all' || loser === 'B') {
                        snake1.status = 'die';
                    }

                    clearInterval(interval_id); // 结束录像
                } else {
                    snake0.set_direction(parseInt(a_steps[k]));
                    snake1.set_direction(parseInt(b_steps[k]));
                }

                k ++ ;
            }, 300);
        } else {
            this.ctx.canvas.focus();
            this.ctx.canvas.addEventListener("keydown", event => { // 获取用户输入
                let d = -1;
                if (event.key === 'w') d = 0;
                else if (event.key === 'd') d = 1;
                else if (event.key === 's') d = 2;
                else if (event.key === 'a') d = 3;
                else if (event.key === 'ArrowUp') d = 0;
                else if (event.key === 'ArrowRight') d = 1;
                else if (event.key === 'ArrowDown') d = 2;
                else if (event.key === 'ArrowLeft') d = 3;
    
                // 进行了合法操作，向后端发送移动请求
                if (d >= 0) {
                    this.store.state.pk.socket.send(JSON.stringify({
                        event: "move",
                        direction: d,
                    }));
                }
            })
        }
    }

    update_size() { // 每一帧更新地图边长
        this.L = parseInt(Math.min(this.parent.clientWidth / this.cols, this.parent.clientHeight / this.rows)); // 求地图内每个小格子的边长
        this.ctx.canvas.width = this.L * this.cols;
        this.ctx.canvas.height = this.L * this.rows;
    }

    next_step() { // 让两条蛇进入下一回合
        for (const snake of this.snakes) {
            snake.next_step();
        }
    }

    check_valid(cell) { // 检测目标点是否合法
        for (const wall of this.walls) { // 是否撞墙
            if (wall.r === cell.r && wall.c == cell.c) {
                return false;
            }
        }

        for (const snake of this.snakes) {
            let len = snake.cells.length;
            if (!snake.check_tail_increasing()) { // 当蛇尾会前进的时候不需要判断
                len -- ;
            }

            for (let i = 0; i < len; i ++ ) { // 是否碰到自己的身体
                if (snake.cells[i].r == cell.r && snake.cells[i].c == cell.c) {
                    return false;
                }
            }
        }

        return true;
    }

    update() {
        this.update_size();
        if (this.check_ready()) { // 如果两条蛇都从键盘输入后
            this.next_step();
        }
        this.render();
    }

    render() { // 渲染，将图像画到游览器上
        const color_even = "#D4F179", color_odd = "#78F1FC"
        for (let r = 0; r < this.rows; r ++ )
            for (let c = 0; c < this.cols; c ++ ) {
                if ((r + c) % 2) {
                    this.ctx.fillStyle = color_even;
                }
                else {
                    this.ctx.fillStyle = color_odd;
                }

                this.ctx.fillRect(c * this.L, r * this.L, this.L, this.L);
            }
                
    }
}